Desenvolvimento para Dispositivos Móveis
Aula 07
Prof. Dr. Raulcézar Alves
raulcezar@gmail.com
Projeto UatZap
- Chat de texto para usuários cadastrados no App.
- Utilizar Firebase para autenticar e armazenar mensagens.
Projeto UatZap
Projeto UatZap
Modificações activity_main.xml
Modificações activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<!-- ADD-->
<ListView
android:id="@+id/listViewMsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:text="Mensagem"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/enviar"
android:text="enviar"
android:onClick="enviarMsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<include layout="@layout/content_main" />
</LinearLayout>
ListView
- A ListView é um grupo de exibições que exibe uma lista de itens roláveis.
- Os itens da lista são inseridos automaticamente na lista usando um Adapter que obtém conteúdo de uma origem como uma matriz ou consulta de banco de dados e converte cada resultado de item em uma exibição, que é colocada na lista.
- Existem vários tipos de ListViews, cada uma serve para uma situação diferente e para resolver problemas diversos em seus aplicativos.
ListView
- A memória de dispositivos móveis é fixa e extremamente limitada.
- É utilizada para armazenar diversos tipos de dados: textos, fotos, vídeos, audios, etc.
- Além disso, é compartilhada por todos os aplicativos do seu dispositivo, inclusive o próprio SO (Android).
ListView
- Apps devem fazer uso inteligente de memória, caso contrário eles podem travar sua execução e também a de outros.
- Imagine um App que mostra todos os seus contatos de uma vez, por exemplo 1.000. Seria necessário 1.000 TextView na tela ocupando memória, sendo que conseguiriamos ver apenas 10.
ListView
- Uma estratégia é reciclagem de Views.
- Podemos criar apenas a quantidade de Views que conseguimos ver na tela, e a medida em que rolamos a lista, dados que não podem mais ser vistos são removidos das Views para dar espaço aos novos.
ListView
- Para utilizar essa estratégia e exibir listas de maneira eficiente, utilizamos algum tipo de ListView (tela) juntamente com um Adapter (java).
- Adapter é responsável por gerenciar e adaptar os dados nas Views, e até criá-las se necessário.
- Existem vários tipos de Adapter, um dos mais utilizados é o ArrayAdapter que pode manipular dados com base em Arrays ou java.util.List.
ListView
Existem dois métodos importantes nos Adapters para fazer a atualização dos dados e avisar as ListViews da tela que algo mudou:
- notifyDataSetChanged(): É chamado se os dados tiverem sido alterados ou se houver novos dados disponíveis.
- notifyDataSetInvalidated(): É chamado se os dados não estiverem mais disponíveis.
ListView
- A ListView é um dos componentes mais utilizados para listar dados na plataforma Android de forma eficiente.
- Basicamente ela organiza os dados um seguido do outro em formato vertical com a opção de rolagem.
- Para utilizar a ListView, primeiro deve-se adicionar o componente no XML da activity (tela).
ListView
- Depois, no controle Java da activity, no método onCreate(), deve-se recuperar o componente pelo ID para utilizá-lo mais tarde, de preferência utilizando o padrão ViewHolder que vimos.
ListView
- Os dados a serem apresentados na ListView podem estar armazenados em um Array, como mostrado abaixo, ou em um Java List.
- Estes dados podem ser estáticos, ou terem vindo por exemplo de uma Base de dados dinamicamente.
ListView
- É necessário instanciar um ArrayAdapter tipando ele com dados do tipo String neste caso.
- No construtor, passe os seguintes parâmetros: Context, ID do layout e a Array de dados.
- No exemplo, é utilizado o layout android.R.layout.simple_list_item_1, padrão para a linha da ListView.
- Depois, o Adapter é adicionado dentro da ListView utilizando o método setAdapter().
ListView
Resumindo:
- dizemos que a ListView da tela (@+id/listview)
- é ligada ao atributo listview no Java
- gerenciado pelo adaptador adapter
- que administra os dados a serem exibidos do vetor dados.
Modificações MainActivity.java
Modificações MainActivity.java
Modificações MainActivity.java
Modificações activity_main.xml
package mobile.pitagoras.uatzap;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class MainActivity extends AppCompatActivity {
private FirebaseAuth mAuth;
private DatabaseReference dbr;//ADD
private ViewHolder vh = new ViewHolder();//ADD
private ArrayList<String> listMsg = new ArrayList<String>();//ADD
private ArrayAdapter arrayAdpt;//ADD
private FirebaseUser user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mAuth = FirebaseAuth.getInstance();
user = mAuth.getCurrentUser();
if (user != null) {
Toast.makeText(getApplicationContext(), "Bem vindo de volta " + user.getEmail() + "!", Toast.LENGTH_LONG).show();
} else {
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
finish();
}
this.vh.msg = (EditText) findViewById(R.id.msg);//ADD
this.vh.listViewMsg = (ListView) findViewById(R.id.listViewMsg);//ADD
arrayAdpt = new ArrayAdapter(this,android.R.layout.simple_list_item_1,listMsg);//ADD
this.vh.listViewMsg.setAdapter(this.arrayAdpt);//ADD
dbr = FirebaseDatabase.getInstance().getReference().getRoot();//ADD
dbr.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Set<String> set = new HashSet<String>();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
ds.getValue();
set.add(ds.getValue().toString());
}
arrayAdpt.clear();
arrayAdpt.addAll(set);
arrayAdpt.notifyDataSetChanged();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_exit) {
mAuth.signOut();
startActivity(new Intent(this, LoginActivity.class));
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
public void enviarMsg(View view) {
android.text.format.DateFormat df = new android.text.format.DateFormat();
String data = df.format("dd/MM/yyyy hh:mm", new java.util.Date()).toString();
String valor = user.getEmail()+": \n"+this.vh.msg.getText().toString()+" \n"+data;
String chave = dbr.push().getKey();
dbr.child(chave).setValue(valor);
}
private class ViewHolder{//ADD
ListView listViewMsg;
EditText msg;
}
}
UatZap
Verifique permissão de internet no AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mobile.pitagoras.uatzap">
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.INTERNET" /><!-- ADD-->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".LoginActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Verifique as versões do Firebase (preferência 16.0.4)
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "mobile.pitagoras.uatzap"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.google.firebase:firebase-auth:16.0.4'
implementation 'com.google.firebase:firebase-core:16.0.4'
implementation 'com.google.firebase:firebase-database:16.0.4'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
apply plugin: 'com.google.gms.google-services'